package vip.ola.pay.channel.daifuchannel.laojiudaifu;

import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import org.springframework.stereotype.Service;
import vip.ola.core.common.constant.PayConstant;
import vip.ola.core.common.util.MyLog;
import vip.ola.core.common.util.PayDigestUtil;
import vip.ola.core.common.util.PayUtil;
import vip.ola.core.entity.AgentpayPassageAccount;
import vip.ola.core.entity.TransOrder;
import vip.ola.pay.channel.BaseTrans;

import java.io.IOException;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;

import static vip.ola.core.common.constant.Constant.UTF8;
import static vip.ola.core.common.constant.PayEnum.ERR_0121;

/**
 * @author: dingzhiwei
 * @date: 17/12/25
 * @description:
 */
@Service
public class LjpayTransService extends BaseTrans {

    private static final MyLog _log = MyLog.getLog(LjpayTransService.class);

    @Override
    public String getChannelName() {
        return PayConstant.CHANNEL_NAME_ALIPAY;
    }

    public JSONObject trans(TransOrder transOrder) {
        JSONObject retObj = buildRetObj();
        try {
            _log.info("代付转账：" + transOrder.getChannelMchId());
            AgentpayPassageAccount payPassageAccount = rpcCommonService.rpcAgentpayPassageAccountService.findById(transOrder.getPassageAccountId());
            if (payPassageAccount == null || StringUtils.isBlank(payPassageAccount.getParam())) {
                return PayUtil.makeRetFail(ERR_0121);
            }
            JSONObject accountParams = JSONObject.parseObject(payPassageAccount.getParam());
            String mchId = payPassageAccount.getPassageMchId();
            String orderId = transOrder.getTransOrderId();
            String payUrl = accountParams.getString("payUrl");
            String privateKey = accountParams.getString("privateKey");
            String payCode = accountParams.getString("payCode");
            String isTests = accountParams.getString("isTest");
            BigDecimal amount = new BigDecimal(transOrder.getAmount()).divide(new BigDecimal(100)).setScale(2);
             Long timeStamp = System.currentTimeMillis()/1000;
            Map<String, Object> obj = new HashMap<>();
            obj.put("Payee", transOrder.getAccountName().trim());
            obj.put("PayeeNo", transOrder.getAccountNo().trim());
            obj.put("Amount", String.valueOf(amount));
            obj.put("AccessKey", mchId);
            obj.put("Timestamp", timeStamp);
            obj.put("PayChannelId", payCode);
            if (StringUtils.isNotEmpty(transOrder.getBankName())){
                obj.put("PayeeAddress", transOrder.getBankName());
            }else {
                obj.put("PayeeAddress", "未知银行");
            }
            obj.put("CallbackUrl", accountParams.getString("notify_url"));
            obj.put("OrderNo", orderId);
            String sign = getSign(obj,privateKey);
            obj.put("Sign", sign);
            _log.info("下单请求url={}，json->{}",payUrl,JSONObject.toJSONString(obj));
            if (StringUtils.isNotEmpty(isTests) && "1".equals(isTests)){
                retObj.put("status",1);
            }else {
                String respData = call(payUrl,obj);
                _log.info("下单结束respData->{}",respData);
                if (StringUtils.isNotEmpty(respData)){
                    JSONObject jsonObject = JSONObject.parseObject(respData);
                    retObj.put("transOrderId", transOrder.getTransOrderId());
                    if (jsonObject != null){
                        String code = jsonObject.getString("Code");
                        if ("0".equals(code)){
                            retObj.put("status",1);
                        }else {
                            retObj.put("status",3);
                            retObj.put("channelErrCode", code);
                            retObj.put("channelErrCode", jsonObject.getString("Message"));
                        }
                    }
                }else {
                    retObj.put("status",3);
                    retObj.put("channelErrCode", "上游系统异常，请稍后重试");
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            retObj.put("status",3);
            retObj.put("channelErrCode", e.getMessage());
        }
        return  retObj;
    }


    public static String call(String url, Map param) {
        CloseableHttpClient httpClient = HttpClientBuilder.create().build();
        HttpPost httpPost = new HttpPost(url);
        // 响应模型
        CloseableHttpResponse response = null;
        String responseContext = null;
        try {
            StringEntity entity = new StringEntity(JSONObject.toJSONString(param), ContentType.APPLICATION_JSON);
            httpPost.setEntity(entity);
            // 由客户端执行(发送)Get请求
            response = httpClient.execute(httpPost);
            // 从响应模型中获取响应实体
            HttpEntity responseEntity = response.getEntity();

            if (responseEntity != null) {
                responseContext = EntityUtils.toString(responseEntity);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                // 释放资源
                if (httpClient != null) {
                    httpClient.close();
                }
                if (response != null) {
                    response.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return responseContext;
    }




    public static String getSign(Map<String,Object> map, String key){
        ArrayList<String> list = new ArrayList<String>();
        for (Map.Entry<String, Object> entry : map.entrySet()) {
            if (null != entry.getValue() && !"".equals(entry.getValue())) {
                if (entry.getValue() instanceof JSONObject) {
                    list.add(entry.getKey() + "=" + PayDigestUtil.getSortJson((JSONObject) entry.getValue()) + "&");
                } else {
                    list.add(entry.getKey() + "=" + entry.getValue() + "&");
                }
            }
        }
        int size = list.size();
        String[] arrayToSort = list.toArray(new String[size]);
        Arrays.sort(arrayToSort, String.CASE_INSENSITIVE_ORDER);
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < size; i++) {
            sb.append(arrayToSort[i]);
        }
        String result = sb.toString();
        result += "SecretKey=" + key;
        _log.info("LjpayTransService Sign Before MD5:" + result);
        result = PayDigestUtil.md5(result, UTF8);
        _log.info("LjpayTransService Sign Result:" + result);
        return result;
    }


    public JSONObject query(TransOrder transOrder) {
        return null;
    }



    @Override
    public JSONObject balance(String payParam) {
        JSONObject accountParams = JSONObject.parseObject(payParam);
        String mchId = "LkMGkRPeBQC5r41KA9AetmzJ";
        String privateKey = accountParams.getString("privateKey");
        String balanceUrl = accountParams.getString("balanceUrl");
        Map<String, Object> obj = new HashMap<>();
        Long timestamp = System.currentTimeMillis()/1000;
        obj.put("Timestamp", timestamp);
        obj.put("AccessKey", mchId);
        String sign = getSign(obj,privateKey);
        obj.put("Sign", sign);
        _log.info("余额查询请求url={}，json->{}",balanceUrl,JSONObject.toJSONString(obj));
        String respData = call(balanceUrl,obj);
        _log.info("余额查询结束respData->{}",respData);
        if (StringUtils.isNotEmpty(respData)){
            JSONObject jsonObject = JSONObject.parseObject(respData);
            if (jsonObject != null){
                String code = jsonObject.getString("Code");
                if ("0".equals(code)  ){
                    String totalAmt = jsonObject.getJSONObject("Data").getString("Balance");
                    JSONObject result = new JSONObject();
                    result.put("retCode","SUCCESS");
                    result.put("cashBalance",totalAmt);
                    return result;
                }
            }
        }
        return null;
    }



    public static void main (String args[]){
    }


}
